#define _XOPEN_SOURCE
#include "apue.h"
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>

#if defined(MACOS)
#include <sys/syslimits.h>
#elif defined(SOLARIS)
#include <limits.h>
#elif defined(BSD)
#include <sys/param.h>
#endif

unsigned long long count;
struct timeval end;

void checktime(char *str);

int main(int argc, char *argv[]) {
    pid_t pid;
    char *s;
    int nzero, ret;
    int adj = 0;

#if defined(NZERO)
    nzero= NZERO;
#elif defined(_SC_NZERO)
    nzero= sysconf(_SC_NZERO);
#else
#error NZERO undefined
#endif

    setbuf(stdout, NULL);
    
    if (argc == 2)
        adj= strtol(argv[1], NULL, 10);
    
    gettimeofday(&end, NULL);
    end.tv_sec+= 10;    /* run for 10 seconds */

    if ((pid= fork()) < 0)        
        err_sys("fork error");
    else if (pid == 0) {    /* child */
        s= "child";       
        printf("current nice value in child is %d, adjusting by %d\n", nice(0)+nzero, adj);
        errno= 0;
        if ((ret= nice(adj)) == -1 && errno > 0)
            err_sys("nice error");
        printf("now child nice value is %d\n", ret+nzero);

    } else {
        s= "parent";
        printf("current nice value in parent is %d\n", nice(0)+nzero);
    }

    while (1) {
        if (++count == 0)
            err_quit("%s counter wrap", s);
        checktime(s);
    }
}

void checktime(char *str) {
    struct timeval now;
    gettimeofday(&now, NULL);
    if (now.tv_sec >= end.tv_sec && now.tv_usec >= end.tv_usec) {
        printf("%s count = %lld\n", str, count);
        exit(0);
    }
}
